package com.jason.library.common.base

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.lifecycle.ViewModelProviders
import com.jason.library.common.R
import com.jason.library.common.base.callback.EmptyCallback
import com.jason.library.common.base.callback.ErrorCallback
import com.jason.library.common.base.callback.LoadingCallback
import com.jason.library.common.base.callback.TimeoutCallback
import com.jason.library.common.util.NetworkUtils
import com.jason.library.common.ext.observe
import com.kingja.loadsir.core.LoadService
import com.kingja.loadsir.core.LoadSir
import java.lang.reflect.ParameterizedType

abstract class BaseStateActivity<VM : BaseViewModel> : BaseActivity() {

    var loadService: LoadService<*>? = null

    var viewModel: VM? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        pageStatusPopulate()
    }

    override fun beforeViewInit() {
        viewModel = obtainViewModel()
        bindLiveData()
    }

    abstract fun bindLiveData()

    private fun pageStatusPopulate() {
        if(needPageStatus()) {
            // Your can change the callback on sub thread directly.
            val loadSir = LoadSir.Builder()
                .addCallback(LoadingCallback())
                .addCallback(EmptyCallback())
                .addCallback(ErrorCallback())
                .addCallback(TimeoutCallback())
                //.setDefaultCallback(LoadingCallback::class.java)
                .build()
            loadService = loadSir.register(getPageTarget()) {
                reload()
            }

            observe(viewModel!!.pageStatusData) {
                when(it.status){
                    Status.LOADING -> loadService!!.showCallback(LoadingCallback::class.java)
                    Status.SUCCESS -> loadService!!.showSuccess()
                    Status.EMPTY -> loadService!!.showCallback(EmptyCallback::class.java)
                    Status.ERROR -> {
                        loadService!!.showCallback(if(NetworkUtils.isConnected) {
                            ErrorCallback::class.java
                        } else {
                            TimeoutCallback::class.java
                        })
                    }
                }

            }

        }
    }


    fun needPageStatus() = true

    abstract fun getPageTarget() : Any

    open fun <VM> getGenericType(`object`: Any, index: Int): Class<VM> {
        return (`object`
            .javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[index] as Class<VM>
    }

    protected open fun obtainViewModel(): VM? {
        return try {
            val modelClass: Class<VM> = getGenericType(this, 0)
            ViewModelProviders.of(this).get(modelClass)
        } catch (e: ClassCastException) {
            //PrettyLogger.e(javaClass.simpleName, e.message)
            null
        }
    }

    abstract fun reload()

}